package com.hk.sdk;

import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import lombok.extern.slf4j.Slf4j;

import java.nio.ByteBuffer;
import java.util.logging.Logger;

/**
 * 调用demo
 *
 * @author JW
 * @version 1.0
 * @date 2021/3/25 14:47
 */
@Slf4j
public class HKNetApp {

	private NativeLong lUserID = new NativeLong(-1);// 用户句柄
	private HCNetSDK.NET_DVR_DEVICEINFO_V30 m_strDeviceInfo;// 设备信息

	static HCNetSDK hCNetSDK = null;// sdk

	public static synchronized void loadLibrary(String libraryPath) {
		if (null == hCNetSDK) {
			hCNetSDK = (HCNetSDK) Native.loadLibrary(libraryPath, HCNetSDK.class);
		}
	}

	public static void main(String[] args) {
		loadLibrary("你的sdk地址");

		HKNetApp hkNetApp = new HKNetApp();

		if (hkNetApp.init() && hkNetApp.login()) {
			Float temperature = hkNetApp.getTemperature(new HKPoint(10.0f, 1.0f), 126, 100);
			log.info("1,1点的温度是,{}", temperature);
		}

		hkNetApp.logout();
		hCNetSDK.NET_DVR_Cleanup();
	}

	/**
	 * SDK初始化
	 * 
	 * @return
	 */
	public Boolean init() {
		if (!hCNetSDK.NET_DVR_Init()) {
			log.error("初始化失败");
			return false;
		}
		return true;
	}

	/*************************************************
	 * 函数: "注册" 按钮单击响应函数 函数描述: 注册登录设备
	 *************************************************/
	public Boolean login() {// GEN-FIRST:event_jButtonLoginActionPerformed
		// 注册之前先注销已注册的用户,预览情况下不可注销
		if (lUserID.longValue() > -1) {
			// 先注销
			hCNetSDK.NET_DVR_Logout_V30(lUserID);
		}
		// 注册
		m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V30();

		lUserID = hCNetSDK.NET_DVR_Login_V30("192.168.8.14", (short) 8000, "admin", "a1234567", m_strDeviceInfo);

		long userID = lUserID.longValue();
		boolean initSuc = hCNetSDK.NET_DVR_SetLogToFile(3, "f:\\sdklog\\", false);

		if (userID == -1) {
			log.error("登录失败,{}", userID);
			return false;
		}
		return true;
	}

	public void logout() {
		hCNetSDK.NET_DVR_Logout_V30(lUserID);
	}

	public Float getTemperature(HKPoint hkPoint, int sourceWidth, int sourceHeight) {
		boolean bRet = false;
		int nErr = 0;
		int erro;
		HCNetSDK.NET_DVR_THERMOMETRY_PRESETINFO m_struThermometryInfo = new HCNetSDK.NET_DVR_THERMOMETRY_PRESETINFO();
		m_struThermometryInfo.dwSize = m_struThermometryInfo.size();

		HCNetSDK.NET_DVR_THERMOMETRY_COND m_struThermometryCond = new HCNetSDK.NET_DVR_THERMOMETRY_COND();
		m_struThermometryCond.dwSize = m_struThermometryCond.size();
		m_struThermometryCond.dwChannel = 1;
		m_struThermometryCond.wPresetNo = 1;
		m_struThermometryCond.write();

		HCNetSDK.NET_DVR_STD_CONFIG struCfg = new HCNetSDK.NET_DVR_STD_CONFIG();
		struCfg.lpCondBuffer = m_struThermometryCond.getPointer();
		struCfg.dwCondSize = m_struThermometryCond.size();
		struCfg.lpOutBuffer = m_struThermometryInfo.getPointer();
		struCfg.dwOutSize = m_struThermometryInfo.size();

		HCNetSDK.BYTE_ARRAY m_szStatusBuf = new HCNetSDK.BYTE_ARRAY(4096 * 4);
		struCfg.lpStatusBuffer = m_szStatusBuf.getPointer();
		struCfg.dwStatusSize = 4096 * 4;
		struCfg.byDataType = 0;

		bRet = hCNetSDK.NET_DVR_GetSTDConfig(lUserID, 3624, struCfg);
		if (!bRet) {
			nErr = hCNetSDK.NET_DVR_GetLastError();
			log.error("NET_DVR_GetSTDConfig失败,{}", nErr);
			return 0f;
		}

		m_struThermometryInfo.dwSize = m_struThermometryInfo.size();
		m_struThermometryInfo.wPresetNo = 1;
		m_struThermometryInfo.struPresetInfo[0] = new HCNetSDK.NET_DVR_THERMOMETRY_PRESETINFO_PARAM();
		m_struThermometryInfo.struPresetInfo[0].byEnabled = 1;
		m_struThermometryInfo.struPresetInfo[0].byRuleID = 1;
		m_struThermometryInfo.struPresetInfo[0].wDistance = 10;
		m_struThermometryInfo.struPresetInfo[0].fEmissivity = (float) 0.9599;
		m_struThermometryInfo.struPresetInfo[0].byReflectiveEnabled = 0;
		m_struThermometryInfo.struPresetInfo[0].fReflectiveTemperature = 20;
		m_struThermometryInfo.struPresetInfo[0].byRuleCalibType = 2;
		// m_struThermometryInfo.struPresetInfo[0].szRuleName ="1"；
		m_struThermometryInfo.struPresetInfo[0].byDistanceUnit = 0;
		// m_struThermometryInfo.struPresetInfo[0].byemissivityMode = 0;
		m_struThermometryInfo.struPresetInfo[0].struPoint = new HCNetSDK.NET_VCA_POINT();
		m_struThermometryInfo.struPresetInfo[0].struPoint.fX = 0;
		m_struThermometryInfo.struPresetInfo[0].struPoint.fY = 0;
		m_struThermometryInfo.struPresetInfo[0].struPoint.write();
		m_struThermometryInfo.struPresetInfo[0].struRegion = new HCNetSDK.NET_VCA_POLYGON();
		m_struThermometryInfo.struPresetInfo[0].struRegion.dwPointNum = 2;
		m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[0] = new HCNetSDK.NET_VCA_POINT();
		m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[0].fX = (float) 0.187;
		m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[0].fY = (float) 0.6119;
		m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[0].write();
		m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[1] = new HCNetSDK.NET_VCA_POINT();
		m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[1].fX = (float) 0.876;
		m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[1].fY = (float) 0.569;
		m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[1].write();
		m_struThermometryInfo.struPresetInfo[0].struRegion.write();
		m_struThermometryInfo.write();
		struCfg.lpInBuffer = m_struThermometryInfo.getPointer();
		struCfg.dwInSize = m_struThermometryInfo.size();

		boolean setSTDConfig = hCNetSDK.NET_DVR_SetSTDConfig(lUserID, 3625, struCfg);
		log.info("NET_DVR_SetSTDConfig,{}", setSTDConfig);

		HCNetSDK.NET_DVR_JPEGPICTURE_WITH_APPENDDATA m_strJpegWithAppenData = new HCNetSDK.NET_DVR_JPEGPICTURE_WITH_APPENDDATA();
		m_strJpegWithAppenData.dwSize = m_strJpegWithAppenData.size();
		m_strJpegWithAppenData.dwChannel = 1;
		HCNetSDK.BYTE_ARRAY ptrJpegByte = new HCNetSDK.BYTE_ARRAY(2 * 1024 * 1024);
		HCNetSDK.BYTE_ARRAY ptrP2PDataByte = new HCNetSDK.BYTE_ARRAY(2 * 1024 * 1024);
		m_strJpegWithAppenData.pJpegPicBuff = ptrJpegByte.getPointer();
		m_strJpegWithAppenData.pP2PDataBuff = ptrP2PDataByte.getPointer();

		bRet = hCNetSDK.NET_DVR_CaptureJPEGPicture_WithAppendData(lUserID, 2, m_strJpegWithAppenData);
		if (bRet) {
			// 测温数据
			if (m_strJpegWithAppenData.dwP2PDataLen > 0) {
				HKPoint point = point2point(hkPoint, sourceWidth, sourceHeight, m_strJpegWithAppenData.dwJpegPicWidth,
						m_strJpegWithAppenData.dwJpegPicHeight);
				return getTemperature0(m_strJpegWithAppenData.pP2PDataBuff
						.getByteBuffer((long) ((m_strJpegWithAppenData.dwJpegPicWidth * point.y + point.x) * 4), 4));
			}
		}

		return 0f;
	}

	private Float getTemperature0(ByteBuffer byteBuffer) {
		byte[] byTempData = new byte[4];
		byteBuffer.get(byTempData);

		int l = byTempData[0];
		l &= 0xff;
		l |= ((long) byTempData[1] << 8);
		l &= 0xffff;
		l |= ((long) byTempData[2] << 16);
		l &= 0xffffff;
		l |= ((long) byTempData[3] << 24);

		return Float.intBitsToFloat(l);
	}

	private HKPoint point2point(HKPoint points, int sourceWidth, int sourceHeight, int targetWidth, int targetHeight) {
		points.x = points.x * sourceWidth / targetWidth;
		points.y = points.y * sourceHeight / targetHeight;

		points.x = points.x >= targetWidth ? targetWidth : points.x;
		points.x = points.x < 0 ? 0 : points.x;

		points.y = points.y >= targetHeight ? targetHeight : points.y;
		points.y = points.y < 0 ? 0 : points.y;

		return points;
	}
}
